package com.lsh.payment.core.service.dmallpay.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.lsh.payment.api.model.basevo.BaseResponse;
import com.lsh.payment.api.model.basevo.ExceptionStatus;
import com.lsh.payment.api.model.dmallpay.DMallContent;
import com.lsh.payment.api.model.dmallpay.DMallResponse;
import com.lsh.payment.api.model.dmallpay.DMallResult;
import com.lsh.payment.api.model.payment.PaymentRequest;
import com.lsh.payment.core.constant.BusinessConstant;
import com.lsh.payment.core.exception.BusinessException;
import com.lsh.payment.core.model.payasync.payTaskModel;
import com.lsh.payment.core.model.payenum.PayChannel;
import com.lsh.payment.core.model.payenum.PayStatus;
import com.lsh.payment.core.model.payenum.PayWay;
import com.lsh.payment.core.model.payenum.TradeModule;
import com.lsh.payment.core.model.payment.PayDeal;
import com.lsh.payment.core.service.async.PayEventBus;
import com.lsh.payment.core.service.paylog.PayLogService;
import com.lsh.payment.core.service.payment.IPayChannelService;
import com.lsh.payment.core.service.payment.impl.PayBaseService;
import com.lsh.payment.core.strategy.config.DMallPayConfig;
import com.lsh.payment.core.strategy.payment.PayStrategyContext;
import com.lsh.payment.core.strategy.vo.dmallpay.DMallPayResponse;
import com.lsh.payment.core.util.PayAssert;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.text.MessageFormat;
import java.util.HashMap;
import java.util.Map;

/**
 * Project Name: lsh-payment
 * Created by panxudong on 17/11/14.
 * 北京链商电子商务有限公司
 * Package
 * desc:
 */
@Service(value = "dmallPayServiceImpl")
@Transactional(readOnly = true)
public class DMallPayServiceImpl implements IPayChannelService {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private PayBaseService payBaseService;

    @Autowired
    private PayLogService payLogService;

    @Value("${profile.name}")
    private String profileName;

    @Resource
    private PayStrategyContext strategies;

    /**
     * 多点预下单
     *
     * @param paymentRequest 多点预下单对象
     * @return 多点预下单结果
     */
    private BaseResponse pay(PaymentRequest paymentRequest) {
        DMallResponse<DMallContent> dMallResponse = new DMallResponse<>();

        //创建PayDeal
        String ext = paymentRequest.getExt();
        paymentRequest.setExt(null);
        PayDeal payDeal = payBaseService.prePayment(paymentRequest);

        //组装请求多点参数
        JSONObject dMallObject = JSONObject.parseObject(ext);

//        if(profileName.contains("test")){
//            dMallObject.put("storeId","1019");
//        }

        //验证请求多点参数
        PayAssert.notNull(paymentRequest.getSystem(), ExceptionStatus.E1002001.getCode(), "system为空");
        PayAssert.notNull(dMallObject.getString("storeId"), ExceptionStatus.E1002001.getCode(), "storeId为空");
        PayAssert.notNull(dMallObject.getString("discountPrice"), ExceptionStatus.E1002001.getCode(), "discountPrice为空");
        PayAssert.notNull(dMallObject.getString("originPrice"), ExceptionStatus.E1002001.getCode(), "originPrice为空");
        PayAssert.notNull(dMallObject.getString("discountAmount"), ExceptionStatus.E1002001.getCode(), "discountAmount为空");
        PayAssert.notNull(dMallObject.getString("wares"), ExceptionStatus.E1002001.getCode(), "wares为空");

        Map<String, String> payParams = new HashMap<>();
        payParams.put("vendorId", DMallPayConfig.REQUEST_VENDORID);
        payParams.put("storeId", dMallObject.getString("storeId"));
        payParams.put("thirdOrderId", payDeal.getPayId());
        payParams.put("terminal", dMallObject.getString("terminal"));
        payParams.put("channel", BusinessConstant.DMALL_REQUEST_CHANNEL);
        payParams.put("discountPrice", dMallObject.getString("discountPrice"));
        payParams.put("originPrice", dMallObject.getString("originPrice"));
        payParams.put("discountAmount", dMallObject.getString("discountAmount"));
        payParams.put("wares", dMallObject.getString("wares"));
        payParams.put("key", DMallPayConfig.REQUEST_KEY);
        payParams.put("url", DMallPayConfig.REQUEST_URL);

        //请求多点
        DMallPayResponse dMallPayResponse = (DMallPayResponse) strategies.generatePayParams(BusinessConstant.DMALLPAY, payParams);

        if (dMallPayResponse == null
                || dMallPayResponse.getCode() == null
                || !dMallPayResponse.getCode().equals(BusinessConstant.DMALL_REQUEST_SUCCESS)
                || !Boolean.TRUE.equals(dMallPayResponse.getSuccess())) {
            logger.info("多点申请支付授权失败 : " + ExceptionStatus.E2001005.getMessage() + " code:" + dMallPayResponse.getCode() +
                    ",success:" + dMallPayResponse.getSuccess() +
                    ",result:" + dMallPayResponse.getResult() + ",msg:" + dMallPayResponse.getMsg());
            throw new BusinessException(ExceptionStatus.E2001005.getCode(), ExceptionStatus.E2001005.getMessage());
        }

        PayEventBus.post(new payTaskModel(payDeal));

        dMallResponse.setContent(this.getDMallContent(payDeal, dMallPayResponse));
        dMallResponse.setRet(Integer.parseInt(ExceptionStatus.SUCCESS.getCode()));
        dMallResponse.setMsg(ExceptionStatus.SUCCESS.getMessage());

        //记录操作日志
        payLogService.insertLog(payDeal.getPayId(), payDeal.getPayPaymentNo(), payDeal.getTradeId(),
                PayStatus.CREATE_PAYMENT.getValue(), BusinessConstant.OPERATE_SUCCESS, JSON.toJSONString(paymentRequest),
                JSON.toJSONString(dMallResponse),paymentRequest.getVenderId());

        return dMallResponse;
    }

    /**
     * 多点预下单返回值
     *
     * @param payDeal          支付记录
     * @param dMallPayResponse 请求多点预下单接口返回结果
     * @return 返回支付平台预下单结果
     */
    private DMallContent getDMallContent(PayDeal payDeal, DMallPayResponse dMallPayResponse) {
        DMallResult result = new DMallResult();
        BeanUtils.copyProperties(dMallPayResponse.getData(), result);

        DMallContent content = new DMallContent();
        content.setTitle(MessageFormat.format(DMallPayConfig.PAY_TITLE_NAME, payDeal.getTradeId()));
        content.setPayPaymentNo(payDeal.getPayPaymentNo());
        content.setChannelName(PayChannel.DMALLPAY.getName());
        content.setAuthedAmount(payDeal.getRequestAmount().toString());
        content.setPayStatus(payDeal.getPayStatus());
        content.setResult(result);

        return content;
    }

    /**
     * app H5
     *
     * @param paymentRequest 多点预下单对象
     * @return BaseResponse
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public BaseResponse prepay(PaymentRequest paymentRequest) {
        paymentRequest.setTrade_module(TradeModule.ORDER.getName());

        if (paymentRequest.getPay_way().equals(PayWay.ANDROID.getName())
                || paymentRequest.getPay_way().equals(PayWay.IOS.getName())
                || paymentRequest.getPay_way().equals(PayWay.H5.getName())
                || paymentRequest.getPay_way().equals(PayWay.WINDOWS.getName())) {
            return this.pay(paymentRequest);
        } else {
            throw new BusinessException(ExceptionStatus.E2001002.getCode(), "pay_way 参数异常");
        }
    }

}
